<template>
    <div style="text-align: center;padding-bottom: 15px;">
        <el-button type="primary" @click="codeSubmit()" :disabled="isSubmit" :loading="isSubmit">
            提交
        </el-button>
    </div>
    <div id="oj-submit">
        <div class="left">
            <SubmitLeftPart />
        </div>
        <div class="right">
            <SubmitRightPart @codeInput="inputCallBack" :codeTemplate="currentSubject?.codeTemplate" />
            <!-- 题目执行结果展示 -->
            <div id="code-run-result">
                {{ runResult }}
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { SubjectSubmitStatusEnum } from '@/common/Constant';
import SubmitLeftPart from '@/components/oj/SubmitLeftPart.vue';
import SubmitRightPart from '@/components/oj/SubmitRightPart.vue';
import { BusinessException } from '@/exception/BusinessException';
import { subjectApi } from '@/request';
import { useOjStores } from '@/stores/ojStores';
import type { SubjectPage } from '@/typedefined/Page';
import type { CodeRunInfo, CodeRunResult, Response } from '@/typedefined/Response';
import type { OjSubject } from '@/typedefined/Subject';
import { pollRequest } from '@/utils/CommonUtils';
import { ElButton, ElMessage } from 'element-plus';
import { storeToRefs } from 'pinia';
import { onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';


const ojStores = useOjStores();
// 当前题目信息
const { currentSubject } = storeToRefs(ojStores);

// route实例
const route = useRoute();

// 用户代码
const userCode = ref<string>("");

// 运行结果
const runResult = ref<string>("");

// 用户输入代码时的回调函数
function inputCallBack(code: string): void {
    userCode.value = code;
}


let isSubmit = ref<boolean>(false);
// 代码提交
async function codeSubmit() {
    try {
        // 防止用户重复点击
        if (isSubmit.value) return;
        isSubmit.value = true;
        // 请求后端接口，拿到响应结果
        const taskId:number = await subjectApi.oj.codeSubmit(currentSubject.value?.id || 0, userCode.value) as unknown as number;
        // 获取任务id
        // 轮询，获取代码执行结果
        pollRequest(1000, subjectApi.oj.getCodeRunResult, (result: CodeRunInfo) => {
            // 如果结果为 null ，代表系统错误
            if(!result) return false;
            // 如果代码正在执行
            if (result.status === SubjectSubmitStatusEnum.PENDING) {
                return true;
            }
            // 测试用例全部通过
            if (result.status === SubjectSubmitStatusEnum.SUCCESS) {
                const r:CodeRunResult = JSON.parse(result.executeResult);
                runResult.value = `恭喜你通过全部测试用例,时间消耗：${r.executionTime}ms，空间消耗：${r.memoryUsed}MB`;
            }
            // 代码执行失败或者测试用例未通过
            if (result.status === SubjectSubmitStatusEnum.ERROR) {
                runResult.value = result.executeResult;
            }
            isSubmit.value = false;
            return false;
        }, taskId);
    }
    catch (e) {
        isSubmit.value = false;
        if (e instanceof BusinessException) {
            throw new BusinessException(e.message);
        }
    }
}

// 组件挂载完毕后的回调函数
onMounted(async () => {
    if (currentSubject.value) return;
    // 用户直接打开该页面，需要通过页面路径id查询对应的题目
    const subjectId: number = route.params.id as unknown as number;
    // 请求后端数据
    const dataPageSubject = await subjectApi.oj.getSubjectList({
        currentPage: 1,
        pageSize: 10,
        id: subjectId
    }) as unknown as SubjectPage<OjSubject>;
    const dataList: Array<OjSubject> = dataPageSubject.records;
    if (!dataList || dataList.length === 0) throw new BusinessException("题目信息不存在");
    currentSubject.value = dataList[0];
});


</script>

<style scoped>
#oj-submit {
    display: flex;
}

#oj-submit>.left {
    flex: 3;
}

#oj-submit>.right {
    flex: 4;
}

#code-run-result {
  width: 90%; /* 宽度自适应，占父容器的90% */
  max-width: 600px; /* 最大宽度限制，可根据需要调整 */
  margin: 20px auto; /* 水平居中，上下外边距20px */
  padding: 20px; /* 内边距 */
  background-color: #f0f8ff; /* 背景颜色，淡蓝色 */
  border: 2px solid #add8e6; /* 边框，浅蓝色 */
  border-radius: 10px; /* 圆角边框 */
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 阴影效果 */
  text-align: center; /* 文本居中 */
  font-family: Arial, sans-serif; /* 字体 */
  font-size: 16px; /* 字体大小 */
  line-height: 1.6; /* 行高 */
  color: #333; /* 字体颜色 */
}
</style>